package com.bf.electroplating.util.word;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.*;

/**
 * Word文档解析器
 * 用于解析包含整改数据的Word文档
 */
@Slf4j
@Component
public class WordDocumentParser {
    
    /**
     * 解析Word文档，提取公司名称和表格数据
     */
    public WordDocumentData parseDocument(String filePath) {
        WordDocumentData documentData = new WordDocumentData();
        documentData.setFilePath(filePath);
        
        try (FileInputStream fis = new FileInputStream(filePath)) {
            XWPFDocument document = new XWPFDocument(fis);
            
            // 1. 提取公司名称（第一行）
            String companyName = extractCompanyName(document);
            documentData.setCompanyName(companyName);
            log.info("提取到公司名称: {}", companyName);
            
            // 2. 提取表格数据
            List<Map<String, String>> tableData = extractTableData(document);
            documentData.setTableData(tableData);
            log.info("提取到{}行表格数据", tableData.size());
            
            // 3. 提取图片信息
            Map<String, String> imageMap = extractImageInfo(document);
            documentData.setImageMap(imageMap);
            log.info("提取到{}张图片", imageMap.size());
            
            document.close();
            
        } catch (IOException e) {
            log.error("解析Word文档失败: {}", filePath, e);
            documentData.setError("解析失败: " + e.getMessage());
        }
        
        return documentData;
    }
    
    /**
     * 提取公司名称（第一段落的文本）
     */
    private String extractCompanyName(XWPFDocument document) {
        try {
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            if (!paragraphs.isEmpty()) {
                XWPFParagraph firstParagraph = paragraphs.get(0);
                String companyName = firstParagraph.getText().trim();
                
                // 清理公司名称，移除可能的格式字符
                companyName = companyName.replaceAll("[\\r\\n\\t]", "").trim();
                
                if (!companyName.isEmpty()) {
                    return companyName;
                }
            }
        } catch (Exception e) {
            log.warn("提取公司名称失败", e);
        }
        
        return "未知公司";
    }
    
    /**
     * 提取表格数据
     */
    private List<Map<String, String>> extractTableData(XWPFDocument document) {
        List<Map<String, String>> tableData = new ArrayList<>();
        
        try {
            List<XWPFTable> tables = document.getTables();
            
            for (XWPFTable table : tables) {
                List<XWPFTableRow> rows = table.getRows();
                
                if (rows.size() < 2) {
                    log.warn("表格行数不足，跳过");
                    continue;
                }
                
                // 第一行是表头，获取列名
                XWPFTableRow headerRow = rows.get(0);
                List<String> headers = new ArrayList<>();
                for (XWPFTableCell cell : headerRow.getTableCells()) {
                    String header = cell.getText().trim();
                    headers.add(header);
                }
                
                log.info("表格列名: {}", headers);
                
                // 从第二行开始提取数据
                for (int i = 1; i < rows.size(); i++) {
                    XWPFTableRow row = rows.get(i);
                    Map<String, String> rowData = new HashMap<>();
                    
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (int j = 0; j < Math.min(cells.size(), headers.size()); j++) {
                        String cellText = cells.get(j).getText().trim();
                        String header = headers.get(j);
                        
                        // 特殊处理图片列，标记为有图片
                        if (isImageColumn(header)) {
                            // 检查单元格中是否有图片
                            boolean hasImage = hasImageInCell(cells.get(j));
                            rowData.put(header, hasImage ? "[图片]" : "");
                        } else {
                            rowData.put(header, cellText);
                        }
                    }
                    
                    // 只添加非空行
                    if (!isEmptyRow(rowData)) {
                        tableData.add(rowData);
                        log.debug("提取行数据: {}", rowData);
                    }
                }
                
                // 通常一个文档只有一个表格，找到后就可以退出
                break;
            }
            
        } catch (Exception e) {
            log.error("提取表格数据失败", e);
        }
        
        return tableData;
    }
    
    /**
     * 判断是否为图片列
     */
    private boolean isImageColumn(String header) {
        if (header == null) return false;
        
        String lowerHeader = header.toLowerCase();
        return lowerHeader.contains("照片") || 
               lowerHeader.contains("图片") || 
               lowerHeader.contains("image") ||
               lowerHeader.contains("photo");
    }
    
    /**
     * 检查单元格中是否有图片
     */
    private boolean hasImageInCell(XWPFTableCell cell) {
        try {
            List<XWPFParagraph> paragraphs = cell.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    if (run.getEmbeddedPictures() != null && !run.getEmbeddedPictures().isEmpty()) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.debug("检查单元格图片失败", e);
        }
        return false;
    }
    
    /**
     * 提取图片信息
     */
    private Map<String, String> extractImageInfo(XWPFDocument document) {
        Map<String, String> imageMap = new HashMap<>();
        
        try {
            // 提取所有图片
            List<XWPFPictureData> allPictures = document.getAllPictures();
            
            for (int i = 0; i < allPictures.size(); i++) {
                XWPFPictureData picture = allPictures.get(i);
                String pictureId = "picture_" + i; // 使用索引作为ID
                String fileName = picture.getFileName();
                
                // 保存图片到临时文件
                String tempPath = saveImageToTemp(picture, fileName);
                if (tempPath != null) {
                    imageMap.put(pictureId, tempPath);
                    log.info("保存图片: {} -> {}", fileName, tempPath);
                }
            }
            
            // 尝试将图片与表格行关联
            Map<String, String> rowImageMap = associateImagesWithRows(document, imageMap);
            imageMap.putAll(rowImageMap);
            
        } catch (Exception e) {
            log.error("提取图片信息失败", e);
        }
        
        return imageMap;
    }
    
    /**
     * 将图片与表格行关联
     */
    private Map<String, String> associateImagesWithRows(XWPFDocument document, Map<String, String> imageMap) {
        Map<String, String> rowImageMap = new HashMap<>();
        
        try {
            List<XWPFTable> tables = document.getTables();
            for (XWPFTable table : tables) {
                List<XWPFTableRow> rows = table.getRows();
                
                for (int rowIndex = 1; rowIndex < rows.size(); rowIndex++) { // 跳过表头
                    XWPFTableRow row = rows.get(rowIndex);
                    List<XWPFTableCell> cells = row.getTableCells();
                    
                    // 检查整改前照片列（通常是第5列，索引4）
                    if (cells.size() > 4) {
                        String beforeImagePath = findImageInCell(cells.get(4), imageMap);
                        if (beforeImagePath != null) {
                            rowImageMap.put((rowIndex - 1) + "_before", beforeImagePath);
                        }
                    }
                    
                    // 检查改造后照片列（通常是第7列，索引6）
                    if (cells.size() > 6) {
                        String afterImagePath = findImageInCell(cells.get(6), imageMap);
                        if (afterImagePath != null) {
                            rowImageMap.put((rowIndex - 1) + "_after", afterImagePath);
                        }
                    }
                }
            }
            
        } catch (Exception e) {
            log.error("关联图片与行失败", e);
        }
        
        return rowImageMap;
    }
    
    /**
     * 在单元格中查找图片
     */
    private String findImageInCell(XWPFTableCell cell, Map<String, String> imageMap) {
        try {
            List<XWPFParagraph> paragraphs = cell.getParagraphs();
            for (XWPFParagraph paragraph : paragraphs) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    List<XWPFPicture> pictures = run.getEmbeddedPictures();
                    for (XWPFPicture picture : pictures) {
                        // 由于API限制，这里简化处理，返回第一张图片
                        if (!imageMap.isEmpty()) {
                            return imageMap.values().iterator().next();
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.debug("查找单元格图片失败", e);
        }
        return null;
    }
    
    /**
     * 保存图片到临时文件
     */
    private String saveImageToTemp(XWPFPictureData picture, String fileName) {
        try {
            // 创建临时目录
            String tempDir = "uploads/word_images/" + 
                java.time.LocalDate.now().toString().replace("-", "/") + "/";
            File dir = new File(tempDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            
            // 生成唯一文件名
            String extension = getFileExtension(fileName);
            String uniqueFileName = UUID.randomUUID().toString().replaceAll("-", "") + extension;
            String filePath = tempDir + uniqueFileName;
            
            // 保存文件
            try (FileOutputStream fos = new FileOutputStream(filePath)) {
                fos.write(picture.getData());
            }
            
            return filePath;
            
        } catch (Exception e) {
            log.error("保存图片失败: {}", fileName, e);
            return null;
        }
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        if (fileName == null || !fileName.contains(".")) {
            return ".jpg"; // 默认扩展名
        }
        return fileName.substring(fileName.lastIndexOf("."));
    }
    
    /**
     * 判断是否为空行
     */
    private boolean isEmptyRow(Map<String, String> rowData) {
        for (String value : rowData.values()) {
            if (value != null && !value.trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * Word文档数据结构
     */
    public static class WordDocumentData {
        private String filePath;
        private String companyName;
        private List<Map<String, String>> tableData;
        private Map<String, String> imageMap;
        private String error;
        
        // Getters and Setters
        public String getFilePath() { return filePath; }
        public void setFilePath(String filePath) { this.filePath = filePath; }
        
        public String getCompanyName() { return companyName; }
        public void setCompanyName(String companyName) { this.companyName = companyName; }
        
        public List<Map<String, String>> getTableData() { return tableData; }
        public void setTableData(List<Map<String, String>> tableData) { this.tableData = tableData; }
        
        public Map<String, String> getImageMap() { return imageMap; }
        public void setImageMap(Map<String, String> imageMap) { this.imageMap = imageMap; }
        
        public String getError() { return error; }
        public void setError(String error) { this.error = error; }
        
        public boolean hasError() { return error != null && !error.isEmpty(); }
    }
}